router: scoped RDS (2/4): support scoped routing configuration#5839
router: scoped RDS (2/4): support scoped routing configuration#5839AndresGuedez wants to merge 28 commits intoenvoyproxy:masterfrom
Conversation
This commit introduces: - Support for scoped routing configuration parsing. - Inline and dynamic config providers using the ConfigProvider framework. - Unit and integration testing scaffolding. This is the second step in the PR chain for envoyproxy#4704. Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
…-dynamic Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
snowp
left a comment
There was a problem hiding this comment.
Looks pretty good from what I can tell, left you come comments to get you started.
api/envoy/api/v2/srds.proto
Outdated
| // The Scoped RDS API is not yet fully implemented and *should not* be enabled in | ||
| // :ref:`envoy_api_msg_config.filter.network.http_connection_manager.v2.HttpConnectionManager`. | ||
|
|
||
| // The resource_names field in DiscoveryRequest specifies a set of route configuration scopes. Each |
There was a problem hiding this comment.
Add ref link to resource_names/DiscoveryRequest?
api/envoy/api/v2/srds.proto
Outdated
| } | ||
| } | ||
|
|
||
| // This configuration represents a set of "scopes", each containing independent routing |
There was a problem hiding this comment.
maybe a set of routing "scopes"?
api/envoy/api/v2/srds.proto
Outdated
| // | ||
| // .. code:: | ||
| // | ||
| // X-Header: a,b;c,d |
There was a problem hiding this comment.
I think using a=b;c=d in the example makes it more obvious that we're parsing key value pairs in this example
api/envoy/api/v2/srds.proto
Outdated
| // Specifies the mechanism for constructing fragments which are composed into keys. | ||
| message FragmentBuilder { | ||
| // Specifies how the value of a header should be extracted. | ||
| // The following example maps the structure of a header to the fields in this message. |
There was a problem hiding this comment.
Maybe include an example of a HeaderValueExtractor that can be used to extract a value from the header
There was a problem hiding this comment.
Added an example in the ScopedRouteConfigurationsSet documentation.
api/envoy/api/v2/srds.proto
Outdated
| } | ||
| } | ||
|
|
||
| // The constructed key consists of the union of these fragments. |
There was a problem hiding this comment.
Yes, updated comment.
| context_.listenerScope())), | ||
| proxy_100_continue_(config.proxy_100_continue()), | ||
| delayed_close_timeout_(PROTOBUF_GET_MS_OR_DEFAULT(config, delayed_close_timeout, 1000)) { | ||
| // Throws an exception on failure. |
There was a problem hiding this comment.
would it be more accurate to say that it throws an exception on invalid config?
| std::shared_ptr<Router::MockConfig> route_config_{new NiceMock<Router::MockConfig>()}; | ||
| }; | ||
|
|
||
| struct ScopedRouteConfigProvider : public Config::ConfigProvider { |
There was a problem hiding this comment.
Is this the same as the one defined in conn_manager_impl_fuzz_test.cc? Maybe define it in some shared file (alongside the mocks?) or maybe reuse the null provider?
There was a problem hiding this comment.
Yes. I've now pulled this out into a common implementation included by both this test and the fuzz_test.
| parseScopedRoutesConfigFromYaml(*resources.Add(), config_yaml); | ||
| EXPECT_THROW(subscription.onConfigUpdate(resources, "1"), ProtoValidationException); | ||
|
|
||
| // 'scope_key_builder.fragments' validation |
There was a problem hiding this comment.
Mind including comments about what is invalid about the configuration? Here and for other invalid config tests. Might also be valuable to verify the exception message to ensure that we're tickling the correct validation
| ~ScopedRoutesConfigProviderManagerTest() override = default; | ||
| }; | ||
|
|
||
| // Tests that the /configdump handler returns the corresponding scoped routing config. |
| - name: envoy.router | ||
| )EOF"; | ||
|
|
||
| HttpConnectionManagerConfig(parseHttpConnectionManagerFromV2Yaml(config_yaml), context_, |
There was a problem hiding this comment.
use EXPECT_NO_THROW to indicate that we don't expect this to throw
mattklein123
left a comment
There was a problem hiding this comment.
A few high level comments from just looking at the API/docs. Thank you for working on this. Cool stuff.
api/envoy/api/v2/srds.proto
Outdated
|
|
||
| oneof extract_type { | ||
| // Specifies the index of the element to extract. | ||
| int32 index = 3; |
There was a problem hiding this comment.
I didn't find mention of signed vs unsigned in Envoy's style guide so I defaulted to Google's style of using signed integers and relying on assertions to check val >= 0.
|
|
||
| // Must be set to true when scoped RDS is enabled. | ||
| // If this is enabled, RDS subscriptions will be triggered by scoped RDS config updates using | ||
| // this configuration as a template. |
|
|
||
| oneof scoped_routes_specifier { | ||
| // Configuration for the Scoped RDS API which dynamically loads routing configuration scopes. | ||
| ScopedRds scoped_rds = 30; |
There was a problem hiding this comment.
Would it be simpler if these options were just in the route_specifier oneof above? Why have them be orthogonal?
There was a problem hiding this comment.
My initial intention keeping them separate was to avoid confusion that SRDS and RDS are tightly coupled and require the same config source, etc.
However, based on the feedback in this review and reassessing this from the user's standpoint, I agree this is simpler if ScopedRds becomes part of the route_specifier, and ScopedRds expands to include both the ConfigSource for RDS and SRDS. This would allow me to remove scoped_rds_template from Rds, which avoids the confusion related to that field (I've never been quite happy with that field since I started working on this).
api/envoy/api/v2/srds.proto
Outdated
| } | ||
| } | ||
|
|
||
| // This configuration represents a set of "scopes", each containing independent routing |
There was a problem hiding this comment.
I'm going to be honest in saying that it's very hard for me to follow the messages/documentation in this file. I read the spec a while ago but I've forgotten it. Would it be possible to add some high level documentation here that walks the end user through some examples of how the API is setup, the fragment builder works, etc. If you plan on doing this in arch overview docs that's fine too, whatever is easiest. The reason I ask for this now is I think it would make it a lot easier to review.
There was a problem hiding this comment.
My initial plan was to add in-depth documentation including examples to the arch overview docs (which I wasn't planning to do until the feature is fully implemented in PR 3), but I agree better documentation in the proto definition would be helpful for this review. I am working on this.
There was a problem hiding this comment.
Thanks a ton. I think even just some YAML examples here in the proto docs would be super helpful. You could move them to the arch overview later or just link to them here, so hopefully zero wasted effort.
|
@snowp @mattklein123 Thanks for the feedback and patience. I wasn't able to work on this last week but I will be actively addressing the comments and updating the PR this week. |
|
This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
|
Apologies for the delay responding to feedback. I have addressed most of the review comments. I am now working on removing the |
api/envoy/api/v2/srds.proto
Outdated
| // which Envoy would fetch via RDS. | ||
| // | ||
| // [#comment:next free field: 4] | ||
| message ScopedRouteConfigurationsSet { |
There was a problem hiding this comment.
Upon revisiting the SRDS proto in the context of Incremental xDS, I have decided to make a few changes after discussing with @htuch.
To easily enable incremental updates to the routing scopes (represented by the Scope message) by leveraging the existing Incremental xDS API, I am going to move the ScopeKeyBuilder specification out of the ScopedRouteConfigurationsSet into the HttpConnectionManager, and instead of publishing a repeated Scope scopes = in this message, each SRDS proto (which will most likely be renamed to ScopedRouteConfiguration) will contain a single Scope.
This change creates much better alignment with the API/protocol already defined for incremental updates, and also simplifies the SRDS API.
I am actively working on this now and will introduce the changes discussed as part of the next few commits to this PR.
There was a problem hiding this comment.
@AndresGuedez cool I will defer looking at the API again until this is done. Thank you for iterating on this.
/wait
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
|
I have made the changes to modify the SRDS API to be delta friendly; what is the best way to move forward with this review? Can this PR be reopened? |
|
@AndresGuedez can you merge master to resolve conflicts? |
…-dynamic Signed-off-by: Andres Guedez <aguedez@google.com>
- Refactor the framework to create a cleaner, more cohesive set of abstractions based on the ConfigProvider::ApiType of the DS API. - Rename base classes for consistency and clarity. Signed-off-by: Andres Guedez <aguedez@google.com>
Merged master and pushed commit with cleanup of the ConfigProvider framework. Actively working on addressing test coverage. |
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
| const ProtobufWkt::Struct& config, | ||
| Protobuf::Message& out_proto); | ||
|
|
||
| #if 0 |
| repeated DynamicRouteConfig dynamic_route_configs = 3 [(gogoproto.nullable) = false]; | ||
| } | ||
|
|
||
| // Envoy's scoped RDS implementation fills this message with all currently loaded route |
There was a problem hiding this comment.
Thanks @AndresGuedez for this, my main thought looking at this is that the PR is too big to reasonably review and without diluting review bandwidth. Can we split the PR up further for review?
I think we should have this master PR kept open to show how things tie together, but then separate PRs for:
- Protos.
- Scoped RDS configuration parser and handling logic. This can just be unit tested and doesn't need to be wired up yet.
- Config subscription and wiring of scoped RDS into the rest of Envoy. The integration test can be added here.
- Optionally, other PRs to reduce the amount of renaming noise, where reasonable.
I think we can get better review velocity if we do it this way.
There was a problem hiding this comment.
Ack. Working on splitting this up.
Implement the scoped RDS (SRDS) API config subscription and provider based on the config protos introduced in #6675 and the ConfigProvider framework introduced in #5243 and #6781. NOTES: See parent PR #5839 for full context into these changes. PRs 2a (#6675) and 2b (#6781) have already been merged. The API is not yet fully implemented. This PR introduces static and dynamic (xDS config subscription) handling of scoped routing configuration, but the new L7 multi tenant routing logic (see #4704) has not yet been introduced. The API is not yet plumbed into the HttpConnectionManager, that will be done in the next PR. This PR includes unit tests only; integration tests will follow in the next PR. Risk Level: Low (this DS API is not yet integrated into the HCM and can not be enabled via config). Testing: Unit tests added. Docs Changes: N/A. Signed-off-by: Andres Guedez <aguedez@google.com>
#7068) Integrate the Scoped Route Discovery Service (SRDS) API into the HttpConnectionManager. NOTES: - This is the last PR in the chain originating from parent #5839. - The scoped routing logic which can be configured through this API has not yet been implemented; it will be done in follow up PRs. Risk Level: Low (API is not yet fully implemented and should not be enabled) Testing: Integration tests added. Signed-off-by: Andres Guedez <aguedez@google.com>
|
I think this is done and can be closed. |
This PR introduces:
This is the second PR in the chain to implement Scoped RDS (see #4704 for design).
NOTE: this PR does not actually implement the scoped routing logic; it will be introduced in the next PR in this chain.
Risk Level: Low; this API is not yet fully implemented and is config guarded (defaulting to disabled)
Testing: Unit and integration tests added
Docs Changes: SRDS (ScopedRouteConfigurationsSet) proto documentation